package com.example.filecopy;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.DocumentsContract;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_SOURCE = 100;
    private static final int REQUEST_CODE_PIC_DEST = 101;
    private static final int REQUEST_CODE_VIO_DEST = 103;
    private static final int REQUEST_STORAGE_PERMISSION = 102;
    private static final String PREFS_NAME = "FileMonitorPrefs";
    private static final String KEY_SOURCE_PATH = "source_path";
    private static final String KEY_DEST_PATH = "dest_path";

    private TextView tvSourcePath, picPath, vioPath, tvLog;
    private String sourcePath, destPath;
    private SharedPreferences prefs;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final Handler handler = new Handler(Looper.getMainLooper());


    private Uri source;
    private Uri targetPic;
    private Uri targetVio;

    Button btnSelectSource;
    Button btnPicSelect;
    Button btnVioSelect;
    Button btnScan;
    Button btnRename;

    private ImageView imageView;

    // 线程池核心优化（根据CPU核心数动态调整）
    private ThreadPoolExecutor fileCopyExecutor;
    private int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); // 核心线程数2-4
    private int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; // 最大线程数
    private long KEEP_ALIVE_SECONDS = 30; // 空闲线程存活时间

    // 延迟时间：2秒（2000毫秒）
    private static final long DELAY_MILLIS = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化SharedPreferences
        prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);

        // 绑定控件
        imageView = findViewById(R.id.iv_firstImage);
        tvSourcePath = findViewById(R.id.tvSourcePath);
        picPath = findViewById(R.id.picPath);
        vioPath = findViewById(R.id.vioPath);
        tvLog = findViewById(R.id.tvLog);
        btnSelectSource = findViewById(R.id.btnSelectSource);
        btnPicSelect = findViewById(R.id.btnPicSelect);
        btnVioSelect = findViewById(R.id.btnVioSelect);
        btnScan = findViewById(R.id.btnScan);
        btnRename = findViewById(R.id.renameBtn);

        // 初始化线程池
        fileCopyExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAXIMUM_POOL_SIZE,
                KEEP_ALIVE_SECONDS,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(), // 任务队列
                new ThreadPoolExecutor.CallerRunsPolicy() // 任务满时的策略（避免任务丢失）
        );

        // 检查权限并加载保存的路径
        checkStoragePermission();
        loadAndVerifySavedPaths(); // 加载并验证路径
        imageView.setImageResource(R.drawable.pre);
        btnScan.setVisibility(View.GONE);
        btnRename.setVisibility(View.GONE);
        // 使用Handler延迟2秒后隐藏图片
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            // 2秒后执行的操作
            imageView.setVisibility(View.GONE); // 隐藏图片
            btnScan.setVisibility(View.VISIBLE);
            // 也可以在这里添加其他操作，如跳转页面等
        }, 2000); // 2000毫秒 = 2秒

        btnRename.setOnClickListener(v -> {
            InputConfirmDialogUtil.showInputDialog(
                    MainActivity.this,
                    "请确认",
                    "",
                    "", // 默认起始序号为1
                    new InputConfirmDialogUtil.InputListener() {
                        @Override
                        public void onConfirm(String input) {
                            try {
                                if (null == input || (null != input && input.length() <= 0)){
                                    Toast.makeText(MainActivity.this, "不能为空", Toast.LENGTH_SHORT).show();
                                }
                                // 校验输入文件夹名是否正确
                                if (!"cpFile".equalsIgnoreCase(input)) {
                                    Toast.makeText(MainActivity.this, "有误", Toast.LENGTH_SHORT).show();
                                    return;
                                }
                                // 执行重命名操作（传入起始序号）
                                renameFiles();
                            } catch (NumberFormatException e) {
                                Toast.makeText(MainActivity.this, "请输入有效的数字", Toast.LENGTH_SHORT).show();
                            }
                        }
                    },
                    btnRename
            );
        });
        // 选择源文件夹
        btnSelectSource.setOnClickListener(v -> selectFolder(REQUEST_CODE_SOURCE));

        // 选择目标图片文件夹
        btnPicSelect.setOnClickListener(v -> selectFolder(REQUEST_CODE_PIC_DEST));

        // 选择目标视频文件夹
        btnVioSelect.setOnClickListener(v -> selectFolder(REQUEST_CODE_VIO_DEST));

        // 扫描并复制文件
        AtomicInteger scanClickCount = new AtomicInteger();
        scanClickCount.set(0);

        AtomicLong firstClickTime = new AtomicLong();
        firstClickTime.set(0);

        AtomicLong reNameTime = new AtomicLong();
        reNameTime.set(0);

        long CLICK_INTERVAL = 10000; // 10秒内多次点击只生效一次
        btnScan.setOnClickListener(v -> {
            if (0 == firstClickTime.get()){
                scanAndCopyFiles();
                firstClickTime.set(System.currentTimeMillis());
            }else {
                if (System.currentTimeMillis() - firstClickTime.get() >= CLICK_INTERVAL){
                    firstClickTime.set(0);
                }
            }


            int i = scanClickCount.get();
            scanClickCount.set(i+ 1);
            if(0 == reNameTime.get()){
                reNameTime.set(System.currentTimeMillis());
            }else {
                if (System.currentTimeMillis() - reNameTime.get() > CLICK_INTERVAL){
                    scanClickCount.set(0);
                    reNameTime.set(0);
                } else if (System.currentTimeMillis() - reNameTime.get() <= CLICK_INTERVAL && scanClickCount.get() >= 10){
                    scanClickCount.set(0);
                    reNameTime.set(0);
                    btnRename.setVisibility(View.VISIBLE);
                }
            }
        });
    }

    // 加载并验证保存的路径（核心优化）
    private void loadAndVerifySavedPaths() {
        String sourceUri = prefs.getString("source_uri", "");
        String tarPicUri = prefs.getString("target_pic_uri", "");
        String tarVioUri = prefs.getString("target_vio_uri", "");
        if (!sourceUri.isEmpty()) {
//            tvSourcePath.setText(getPathFromUri(Uri.parse(sourceUri)));
            btnSelectSource.setVisibility(View.GONE);
        }
        if (!tarPicUri.isEmpty()) {
//            picPath.setText(getPathFromUri(Uri.parse(tarPicUri)));
            btnPicSelect.setVisibility(View.GONE);
        }
        if (!tarVioUri.isEmpty()) {
//            vioPath.setText(getPathFromUri(Uri.parse(tarVioUri)));
            btnVioSelect.setVisibility(View.GONE);
        }
    }

    // 验证路径是否为有效的文件夹
    private boolean isValidFolder(String path) {
        if (path == null || path.isEmpty()) return false;
        File folder = new File(path);
        return folder.exists() && folder.isDirectory() && folder.canRead();
    }


    // 保存文件夹路径
    private void savePath(String key, String path) {
        prefs.edit().putString(key, path).apply();
    }

    // 检查存储权限
    private void checkStoragePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                log("请授予「所有文件访问权限」以正常使用");
                Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivity(intent);
            }
        } else {
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED
                    || ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_STORAGE_PERMISSION);
            }
        }
    }

    // 选择文件夹
    private void selectFolder(int requestCode) {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // 一加手机特定配置，确保能正确显示所有存储位置
        intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
        startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK && data != null) {
            Uri uri = data.getData();
            if (uri != null) {
                // 持久化URI权限（关键：确保一加手机重启后仍能访问）
                getContentResolver().takePersistableUriPermission(
                        uri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION |
                                Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                );

                String path = getPathFromUri(uri);
                if (requestCode == REQUEST_CODE_SOURCE) {
                    savePath("source_uri", uri.toString());
                    tvSourcePath.setText(path);
                } else if (requestCode == REQUEST_CODE_PIC_DEST) {
                    savePath("target_pic_uri", uri.toString());
                    picPath.setText(path);
                }else if (requestCode == REQUEST_CODE_VIO_DEST){
                    savePath("target_vio_uri", uri.toString());
                    vioPath.setText(path);
                }
            }
        } else if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (!isStorageManagerGranted()) {
                Toast.makeText(this, "请授予存储管理权限以正常使用", Toast.LENGTH_LONG).show();
            }
        }
    }

    // 适配一加手机的存储权限检查
    private boolean isStorageManagerGranted() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return Environment.isExternalStorageManager();
        }
        return true;
    }

    // 从URI获取路径（适配一加手机的存储结构）
    private String getPathFromUri(Uri uri) {
        DocumentFile docFile = DocumentFile.fromTreeUri(this, uri);
        if (docFile != null && docFile.exists()) {
            return docFile.getName();
        }
        return uri.getPath();
    }

    // 更可靠的Uri转路径方法
    private String parseUriToPath(Uri uri) {
        if (DocumentsContract.isDocumentUri(this, uri)) {
            String docId = DocumentsContract.getDocumentId(uri);
            // 处理内置存储
            if (docId.startsWith("primary:")) {
                return Environment.getExternalStorageDirectory() + "/" + docId.substring("primary:".length());
            }
            // 处理SD卡（适配更多设备）
            else if (docId.contains(":")) {
                String[] parts = docId.split(":", 2);
                if (parts.length == 2) {
                    // 尝试获取SD卡根目录
                    File externalDir = Environment.getExternalStorageDirectory();
                    if (externalDir != null) {
                        return externalDir.getParent() + "/" + parts[0] + "/" + parts[1];
                    }
                }
            }
        }
        return null;
    }

    // 扫描并复制文件
    private void scanAndCopyFiles() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
        Date nowDate = new Date();
        // 10分钟 = 10 * 60 * 1000 毫秒
        long tenMinutesAgoTime = nowDate.getTime() - 30 * 60 * 1000;
        Date tenMinutesAgoDate = new Date(tenMinutesAgoTime);

        List<String> filesToCopy = new ArrayList<>();
        String sourceUri = prefs.getString("source_uri", "");
        String tarPicUri = prefs.getString("target_pic_uri", "");
        String tarVioUri = prefs.getString("target_vio_uri", "");

        source = Uri.parse(sourceUri);
        targetPic = Uri.parse(tarPicUri);
        targetVio = Uri.parse(tarVioUri);

        DocumentFile sourceDir = DocumentFile.fromTreeUri(this, source);

        DocumentFile[] files = sourceDir.listFiles();
        if (files != null) {
            for (DocumentFile file : files) {
                if (file.isFile()){
                    String fileName = file.getName();
                    if (!(fileName.contains("jpg") || fileName.contains("mp4"))){
                        continue;
                    }
                    filesToCopy.add(fileName);
                }
            }
        } else {
            updateUI(() -> log("无法读取源文件夹，请检查权限"));
        }

        // 原子计数器：跟踪复制进度
        AtomicInteger copiedCount = new AtomicInteger(0);
        Uri target = null;
        if (null != filesToCopy && filesToCopy.size() > 0){
            for (int i = 0; i < filesToCopy.size(); i++) {
                final String fileName = filesToCopy.get(i);
                if (fileName.endsWith(".jpg")){
                    target = targetPic;
                }else if (fileName.endsWith("mp4")){
                    target = targetVio;
                }
                DocumentFile tarDir = DocumentFile.fromTreeUri(this, target);
                fileCopyExecutor.execute(() -> {
                    String copyName = fileName;
                    DocumentFile sourceFile = sourceDir.findFile(copyName);
                    String fileTime = getFileTime(copyName);
                    try {
                        Date fileDate = fmt.parse(fileTime);
                        if (isDateInRange(fileDate,tenMinutesAgoDate,nowDate)){
                            int lastDotIndex = copyName.lastIndexOf('.');
                            copyName = lastDotIndex != -1 ? copyName.substring(0, lastDotIndex) : copyName;

                            DocumentFile destFile = tarDir.findFile(copyName);
                            if (null != destFile && destFile.exists()){
                                return;
                            }
                            destFile = tarDir.createFile(getMimeType(copyName), copyName);
                            // 复制文件内容（适配一加手机的文件读写机制）
                            try (InputStream in = getContentResolver().openInputStream(sourceFile.getUri());
                                 OutputStream out = getContentResolver().openOutputStream(destFile.getUri())) {

                                if (in == null || out == null) {
                                    return;
                                }

                                byte[] buffer = new byte[4096];
                                int bytesRead;
                                while ((bytesRead = in.read(buffer)) != -1) {
                                    out.write(buffer, 0, bytesRead);
                                }
                                copiedCount.incrementAndGet();

                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }


    //批量重命名文件
    private void renameFiles(){
        String tarPicUri = prefs.getString("target_pic_uri", "");
        Uri picUri = Uri.parse(tarPicUri);
        String tarVioUri = prefs.getString("target_vio_uri", "");
        Uri vioUri = Uri.parse(tarVioUri);

        DocumentFile picDir = DocumentFile.fromTreeUri(this, picUri);
        DocumentFile vioDir = DocumentFile.fromTreeUri(this, vioUri);

        List<DocumentFile> renameList = new ArrayList<>();
        List<String> reFileNames = new ArrayList<>();
        //处理图片重命名
        List<DocumentFile> picList = new ArrayList<>();
        DocumentFile[] picFiles = picDir.listFiles();
        if (null != picFiles && picFiles.length > 0) {
            for (DocumentFile file : picFiles) {
                if (file.isFile() && !reFileNames.contains(file.getName())){
                    picList.add(file);
                    reFileNames.add(file.getName());
                }
            }
            if (picList.size() > 0) renameList.addAll(picList);
        }
        //处理视频重命名
        List<DocumentFile> vioList = new ArrayList<>();
        DocumentFile[] vioFiles = vioDir.listFiles();
        if (null != vioFiles && vioFiles.length > 0) {
            for (DocumentFile file : vioFiles) {
                if (file.isFile() && !reFileNames.contains(file.getName())){
                    reFileNames.add(file.getName());
                    vioList.add(file);
                }
            }
            if (vioList.size() > 0) renameList.addAll(vioList);
        }

        //重命名
        if (renameList.size() > 0){
            for (DocumentFile renameFile : renameList) {
                String name = renameFile.getName();
                String newName = "";
                if (name.endsWith(".jpg")) continue;
                if (name.endsWith(".mp4")) continue;

                if (name.startsWith("VID")){
                    newName = name + ".mp4";
                }else if (name.startsWith("IMG")){
                    newName = name + ".jpg";
                }else {
                    continue;
                }
                renameFile.renameTo(newName);
            }
        }
    }

    private String getMimeType(String fileName) {
        int lastDot = fileName.lastIndexOf('.');
        if (lastDot > 0) {
            String extension = fileName.substring(lastDot + 1).toLowerCase();
            switch (extension) {
                case "jpg":
                case "jpeg":
                    return "image/jpeg";
                case "png":
                    return "image/png";
                case "pdf":
                    return "application/pdf";
                case "txt":
                    return "text/plain";
                default:
                    return "application/octet-stream";
            }
        }
        return "application/octet-stream";
    }

    public String getFileTime(String fileName){
        if (fileName.contains("_")){
            fileName = fileName.replace("_01","");
            fileName = fileName.replace("_02","");
            fileName = fileName.replace("_03","");
            fileName = fileName.replace("_04","");
            fileName = fileName.replace("_05","");
        }
        int lastDotIndex = fileName.lastIndexOf('.');
        fileName = lastDotIndex != -1 ? fileName.substring(0, lastDotIndex) : fileName;
        Pattern NON_DIGIT_PATTERN = Pattern.compile("[^0-9]");
        String fileTime = fileName;
        return NON_DIGIT_PATTERN.matcher(fileTime).replaceAll("");
    }

    public static boolean isDateInRange(Date target, Date start, Date end) {
        // 空值检查
        if (target == null || start == null || end == null) {
            throw new IllegalArgumentException("日期参数不能为null");
        }

        // 获取时间戳（毫秒数）
        long targetTime = target.getTime();
        long startTime = start.getTime();
        long endTime = end.getTime();

        // 确保开始时间不晚于结束时间
        if (startTime > endTime) {
            Date temp = start;
            start = end;
            end = temp;
            startTime = start.getTime();
            endTime = end.getTime();
        }

        // 检查是否在范围内（包含边界）
        return targetTime >= startTime && targetTime <= endTime;
    }

    // 复制文件
    private boolean copyFile(File source, File dest) {
        if (dest.exists()) {
            log("文件已存在，跳过: " + dest.getName());
            return true;
        }

        try (FileChannel inChannel = new FileInputStream(source).getChannel();
             FileChannel outChannel = new FileOutputStream(dest).getChannel()) {
            inChannel.transferTo(0, inChannel.size(), outChannel);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 日志记录
    private void log(String message) {
        String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
        String logText = tvLog.getText() + "\n[" + time + "] " + message;
        tvLog.setText(logText);
        tvLog.post(() -> tvLog.scrollTo(0, tvLog.getBottom()));
    }

    // UI更新
    private void updateUI(Runnable runnable) {
        handler.post(runnable);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                log("存储权限已授予");
                loadAndVerifySavedPaths(); // 权限授予后重新验证路径
            } else {
                log("需要存储权限才能正常工作");
                checkStoragePermission();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 回到APP时重新验证路径（避免文件夹被删除或权限变更）
        loadAndVerifySavedPaths();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        executor.shutdown();
    }
}